//
//  ImageUtlity.m
//  PixelTest
//
//  Created by Han Guoxiang on 12-7-12.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "ImageUtlity.h"

#define SAFECOLOR(color) MIN(255,MAX(0,color))

#include <sys/time.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

// Return a bitmap context using alpha/red/green/blue byte values 
CGContextRef CreateRGBABitmapContext (CGImageRef inImage) 
{
	CGContextRef context = NULL; 
	CGColorSpaceRef colorSpace; 
	void *bitmapData; 
	int bitmapByteCount; 
	int bitmapBytesPerRow;
	size_t pixelsWide = CGImageGetWidth(inImage); 
	size_t pixelsHigh = CGImageGetHeight(inImage); 
	bitmapBytesPerRow	= (pixelsWide * 4); 
	bitmapByteCount	= (bitmapBytesPerRow * pixelsHigh); 
	colorSpace = CGColorSpaceCreateDeviceRGB();
	if (colorSpace == NULL) 
	{
		fprintf(stderr, "Error allocating color space\n"); return NULL;
	}
	// allocate the bitmap & create context 
	bitmapData = malloc( bitmapByteCount ); 
	if (bitmapData == NULL) 
	{
		fprintf (stderr, "Memory not allocated!"); 
		CGColorSpaceRelease( colorSpace ); 
		return NULL;
	}
	context = CGBitmapContextCreate (bitmapData, 
                                     pixelsWide, 
                                     pixelsHigh, 
                                     8, 
                                     bitmapBytesPerRow, 
                                     colorSpace, 
                                     kCGImageAlphaPremultipliedLast);
	if (context == NULL) 
	{
		free (bitmapData); 
		fprintf (stderr, "Context not created!");
	} 
	CGColorSpaceRelease( colorSpace ); 
	return context;
}

// Return Image Pixel data as an RGBA bitmap 
unsigned char *RequestImagePixelData(UIImage *inImage) 
{
	CGImageRef img = [inImage CGImage]; 
	CGSize size = [inImage size];
	CGContextRef cgctx = CreateRGBABitmapContext(img); 
	
	if (cgctx == NULL) 
		return NULL;
	
	CGRect rect = {{0,0},{size.width, size.height}}; 
	CGContextDrawImage(cgctx, rect, img); 
	unsigned char *data = CGBitmapContextGetData (cgctx); 
	CGContextRelease(cgctx);
	return data;
}

static ImageUtlity *instance;

@implementation ImageUtlity

+(ImageUtlity *)sharedInstance
{
    if(instance==nil)
    {
        instance=[[ImageUtlity alloc] init];
    }
    return instance;
}

-(void)dealloc
{
    [instance release];
    instance=nil;
    [super dealloc];
}

-(UIImage *)changedImageFrom:(UIImage *)inImage pixel:(PixelColor)pixel value:(CGFloat)value
{
    if(inImage==nil)
    {
        NSLog(@"要处理的图片是nil");
        return nil;
    }
    unsigned char *imgPixel = RequestImagePixelData(inImage);
	CGImageRef inImageRef = [inImage CGImage];
	GLuint w = CGImageGetWidth(inImageRef);
	GLuint h = CGImageGetHeight(inImageRef);
	
	int wOff = 0;
	int pixOff = 0;
    
//    int alpha = (unsigned char)imgPixel[pixOff];
    int red = (unsigned char)imgPixel[pixOff];
    int green = (unsigned char)imgPixel[pixOff+1];
    int blue = (unsigned char)imgPixel[pixOff+2];
    int avgNumber=128;
//    int bw = (int)((red+green+blue)/3.0);
	
	for(GLuint y = 0;y< h;y++)
	{
		pixOff = wOff;
		
		for (GLuint x = 0; x<w; x++) 
		{   
            switch (pixel) {
                case PixelRed:
                    imgPixel[pixOff]=value;
//                    imgPixel[pixOff]+=value;
//                    if(imgPixel[pixOff]>255)
//                    {
//                        imgPixel[pixOff]=255;
//                    }
//                    if(imgPixel[pixOff]<0)
//                    {
//                        imgPixel[pixOff]=0;
//                    }
                    break;
                case PixelGreen:
                    imgPixel[pixOff+1]=value;
//                    imgPixel[pixOff+1]+=value;
//                    if(imgPixel[pixOff+1]>255)
//                    {
//                        imgPixel[pixOff+1]=255;
//                    }
//                    if(imgPixel[pixOff+1]<0)
//                    {
//                        imgPixel[pixOff+1]=0;
//                    }
//
                    break;
                case PixelBlue:
                    imgPixel[pixOff+2]=value;
//                    imgPixel[pixOff+2]+=value;
//                    if(imgPixel[pixOff+2]>255)
//                    {
//                        imgPixel[pixOff+2]=255;
//                    }
//                    if(imgPixel[pixOff+2]<0)
//                    {
//                        imgPixel[pixOff]=0;
//                    }

                    break;
                case PixelBright:                       //亮度调节是将rgb同时变化,+或者- 一个定值
                {        
                    for(int i=0;i<3;i++)
                    {
                        imgPixel[pixOff+i]+=value;
                        if(imgPixel[pixOff+i]<0)
                        {
                            imgPixel[pixOff+i]=0;
                        }
                        if(imgPixel[pixOff+i]>255)
                        {
                            imgPixel[pixOff+i]=255;
                        }
                    }
                }
                    break;
                case PixelContrast:                     //对比度调节即图像上的像素值以128为均点，大于128的向255变化，小于128的向0变化，
                                                        //PS对比度计算公式nRGB = RGB + (RGB – Threshold) * Contrast / 255
                {
                    imgPixel[pixOff]=avgNumber+(red-avgNumber)*value/255;
                }
                    break;
                default:
                    break;
            }
			imgPixel[pixOff+3]=value;
            
			pixOff += 4;
		}
		wOff += w * 4;
	}
	
	NSInteger dataLength = w*h* 4;
	CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);
	// prep the ingredients
	int bitsPerComponent = 8;
	int bitsPerPixel = 32;
	int bytesPerRow = 4 * w;
	CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
	CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
	CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
	
	// make the cgimage
	CGImageRef imageRef = CGImageCreate(w, h, 
                                        bitsPerComponent, 
                                        bitsPerPixel, 
                                        bytesPerRow, 
                                        colorSpaceRef, 
                                        bitmapInfo, 
                                        provider, 
                                        NULL, NO, renderingIntent);
	
	UIImage *my_Image = [UIImage imageWithCGImage:imageRef];
	
	CFRelease(imageRef);
	CGColorSpaceRelease(colorSpaceRef);
	CGDataProviderRelease(provider);
	return my_Image;
}

  
#define MIRRORED ((image.imageOrientation == UIImageOrientationUpMirrored) || (image.imageOrientation == UIImageOrientationLeftMirrored) || (image.imageOrientation == UIImageOrientationRightMirrored) || (image.imageOrientation == UIImageOrientationDownMirrored))	
#define ROTATED90	((image.imageOrientation == UIImageOrientationLeft) || (image.imageOrientation == UIImageOrientationLeftMirrored) || (image.imageOrientation == UIImageOrientationRight) || (image.imageOrientation == UIImageOrientationRightMirrored))

- (UIImage *) doUnrotateImage: (UIImage *) image
{
	CGSize size = image.size;
	if (ROTATED90) size = CGSizeMake(image.size.height, image.size.width);
	
	UIGraphicsBeginImageContext(size);
	CGContextRef context = UIGraphicsGetCurrentContext();
	CGAffineTransform transform = CGAffineTransformIdentity;
    
	// Rotate as needed
	switch(image.imageOrientation)
	{  
        case UIImageOrientationLeft:
		case UIImageOrientationRightMirrored:
			transform = CGAffineTransformRotate(transform, M_PI / 2.0f);
			transform = CGAffineTransformTranslate(transform, 0.0f, -size.width);
			size = CGSizeMake(size.height, size.width);
			CGContextConcatCTM(context, transform);
            break;
        case UIImageOrientationRight: 
		case UIImageOrientationLeftMirrored:
			transform = CGAffineTransformRotate(transform, -M_PI / 2.0f);
			transform = CGAffineTransformTranslate(transform, -size.height, 0.0f);
			size = CGSizeMake(size.height, size.width);
			CGContextConcatCTM(context, transform);
            break;
		case UIImageOrientationDown:
		case UIImageOrientationDownMirrored:
			transform = CGAffineTransformRotate(transform, M_PI);
			transform = CGAffineTransformTranslate(transform, -size.width, -size.height);
			CGContextConcatCTM(context, transform);
			break;
        default:  
			break;
    }
	
    
	if (MIRRORED)
	{
		// de-mirror
		transform = CGAffineTransformMakeTranslation(size.width, 0.0f);
		transform = CGAffineTransformScale(transform, -1.0f, 1.0f);
		CGContextConcatCTM(context, transform);
	}
    
	// Draw the image into the transformed context and return the image
	[image drawAtPoint:CGPointMake(0.0f, 0.0f)];
    UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();  
    return newimg;  
}	

@end
